import json
import os
import queue
import time    
from websocket import create_connection    
import threading    
import random    
import string    
import uuid  
import platform
from enum import Enum
from dataclasses import dataclass



class ScriptState(Enum):
    start = 1
    stop = 2
    pause = 3



    
# 生成一个指定长度的随机数字字符串  
def generate_random_string(length):    
    characters = string.digits    
    random_string = ''.join(random.choices(characters, k=length))    
    return random_string   

def get_unique_id():
    # 获取主板序列号
    if platform.system() == "Windows":
        command = "wmic csproduct get uuid"
        result = os.popen(command).read()
        return result.split('\n')[2].strip()
    
    # 获取硬盘序列号（仅在Linux和MacOS中）
    elif platform.system() == "Linux" or platform.system() == "Darwin":
        command = "cat /sys/class/dmi/id/board_serial"
        result = os.popen(command).read().strip()
        return result
    
    # 如果没有权限获取硬件信息，可以生成一个基于主机名和MAC地址的UUID
    else:
        return uuid.uuid5(uuid.NAMESPACE_DNS, platform.node()).hex 
    
class ConsoleClient:    
    # 初始化客户端WebSocket连接   
    def __init__(self, config):    
        self.url = config["url"] + f"?uuid={get_unique_id()}"  
        self.pending_requests = {}  
        self.response_data = {}  # 存储响应数据  
        self.scripts = config["scripts"]
        self._lock = threading.Lock()  
        self.request_id = 1  
        self.ScriptInfo = {
            "startEvent" : False ,
            "stopEvent" : False ,
            "pauseEvent" : True ,
            "scriptName" : "" ,
            "accountInfo" : {
                "username" : "" ,
                "password" : "" ,
                "card_key" : "" 
            } ,
        }
        self.custom_handlers = {}  # 字典用于存储自定义处理函数
        self._register_handler("assignAccount", self.on_assign_account)
        self._register_handler("heart", self.on_heartbeat)
        self._register_handler("startScript", self.on_startScript)
        self._register_handler("stopScript", self.on_stopScript)
        self._register_handler("pauseScript", self.on_pauseScript)
        self.ws = None    
        self.connect()    
        self.start_listening()    

    
    # 连接到WebSocket服务器  
    def connect(self):    
        self.ws = create_connection(self.url)    
        print("WebSocket connected to: " + self.url)    
    
    # 发送消息到WebSocket服务器  
    def send_message(self, message):    
        if self.ws is not None:    
            self.ws.send(message)    
            print("Sent message: " + message)    
        else:    
            print("WebSocket is not connected.")    
    
    # 接收来自WebSocket服务器的消息  
    def receive_messages(self):    
        while self.ws is not None:    
            try:    
                result = self.ws.recv()    
                message = json.loads(result)    
                print("Received message: " + result)    
                self.handle_message(message)    
            except Exception as e:    
                print("Error receiving message: " + str(e))    
                break    
    
    def _register_handler(self, cmd, handler):
        self.custom_handlers[cmd] = handler

    def _send_request(self, message):  
        if self.ws is None or not self.ws.connected:  
            raise Exception('_send_request failed, websocket not connected')  

        try:  
            with self._lock:  
                id = self.request_id  
                self.request_id += 1  
                message["request_id"] = id  
                self.pending_requests[id] = queue.Queue()  
                self.ws.send(message)  

            response = self.pending_requests[id].get()  
            with self._lock:  
                del self.pending_requests[id]  

        except Exception as e:  
            print(f"Error in _send_request: {e}")  
            response = None  

        return response  
    
    def api_sendText(self , text):
        info = {
            "cmd" : "sendText" ,
            "text" : text
        }
        with self._lock:
            self.ws.send(json.dumps(info))

    # 处理接收到的消息  
    def handle_message(self, message):    
        with self._lock:  
            request_id = message.get("request_id")  
            if request_id <= 0:  
                # 调用自定义处理函数
                cmd = message.get("cmd")
                if cmd in self.custom_handlers:
                    self.custom_handlers[cmd](message)
                else:
                    print(f"_handle_messages warning: No handler registered for response type {cmd}")
            if request_id in self.pending_requests:  
                self.response_data[request_id] = message  
                self.pending_requests[request_id].put(message)  

    
    # 处理getScripts命令  
    def send_scripts(self):    
        reply = {    
            "cmd": "getScripts",    
            "scripts": self.scripts   
        }    
        self.send_message(json.dumps(reply))    
  
    # 处理心跳命令  
    def on_heartbeat(self, message):  
        reply = {    
            "cmd": "heart",    
            "id": message.get("id"),    
        }    
        self.send_message(json.dumps(reply))  

    def on_startScript(self , message):
        self.ScriptInfo["scriptName"] = message.get("scriptName")
        self.ScriptInfo["startEvent"] =  True
        self.ScriptInfo["pauseEvent"] =  False
        print(f"on_startScript")

    def on_stopScript(self , message):
        self.ScriptInfo["stopEvent"] =  True
        print(f"on_stopScript")

    def on_pauseScript(self , message):
        self.ScriptInfo["pauseEvent"] =  True
        print(f"on_pauseScript")
              

    # 处理服务器分配账号的命令  
    def on_assign_account(self, message):
        account_info = message.get("account_info")
        if account_info:
            self.ScriptInfo["accountInfo"]["usename"] = account_info.get("usename")
            self.ScriptInfo["accountInfo"]["password"] = account_info.get("password")
            self.ScriptInfo["accountInfo"]["card_key"] = account_info.get("card_key")

            self.send_scripts()
            # print(f"Received account info: Account={self.ScriptInfo["accountInfo"]["usename"]}, Password={self.ScriptInfo["accountInfo"]["password"]}, Card Key={self.ScriptInfo["accountInfo"]["card_key"]}, UUID={uuid}")

        else:
            print("No account info received")
    
    # 在单独的线程中开始监听消息  
    def start_listening(self):    
        threading.Thread(target=self.receive_messages, daemon=True).start()    
    
    # 关闭WebSocket连接  
    def close(self):    
        if self.ws is not None:    
            self.ws.close()    
            print("WebSocket connection closed.")    

    def api_GetScriptInfo(self):
        with self._lock:
            return self.ScriptInfo
        

    







